package com.mobile.check.present;

import android.os.Environment;
import android.text.TextUtils;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import cn.droidlover.xdroidmvp.kit.Kits;
import cn.droidlover.xdroidmvp.kit.NLog;
import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.functions.Action;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.functions.Predicate;
import io.reactivex.schedulers.Schedulers;
import com.mobile.check.activitys.TaskListActivity;
import com.mobile.check.beans.TaskInfo;
import com.mobile.check.beans.TaskItemInfo;
import com.mobile.check.db.EntityManager;
import com.mobile.check.util.DoubleUtil;
import com.mobile.check.util.TaskTypeEnum;
import com.mobile.check.util.UploadHelper;

/**
 * 类名: JiancePresent
 * 作者: 李学伟
 * 日期: 2020年10月13日 11:31
 * 描述:
 */
public class TaskListPresent extends BasePresent<TaskListActivity> {

    public void queryTaskInfo(final boolean isLocal, TaskTypeEnum typeEnum) {
        if (isLocal) {
            queryLocalTask(typeEnum);
        }else{
            queryServerTask(typeEnum);
        }
    }

    private void queryLocalTask(TaskTypeEnum typeEnum){
        final List<TaskInfo> dataList = new ArrayList<>();
        String dir;
        final int taskType = typeEnum.getType();
        dir = "本地任务";
        File sd = Environment.getExternalStorageDirectory();
        File f = new File(sd.getPath().concat("/").concat("检测系统").concat("/")
                .concat(dir)
                .concat("/")
                .concat(typeEnum.getName())
                .concat("/")); //获取文件句柄
        File[] files = f.listFiles();
        if (null == files || files.length == 0) {
            getV().showToast("您还没有添加任务文件");
            return;
        }
        Observable.fromArray(files).filter(new Predicate<File>() {
            @Override
            public boolean test(File file) throws Exception {
                String fileName = file.getName();
                return fileName.endsWith(".xlsx");
            }
        }).map(new Function<File, TaskInfo>() {
            @Override
            public TaskInfo apply(File file) throws Exception {
                String taskName = Kits.File.getFileNameWithoutExtension(file.getPath());
                TaskInfo taskInfo = EntityManager.getInstance().queryTaskInfoCount(taskName, taskType, true);
                if (taskInfo == null) {
                    taskInfo = new TaskInfo();
                    String fileName = Kits.File.getFileNameWithoutExtension(file.getPath());
                    taskInfo.setTask_name(fileName);
                    taskInfo.setTaskFilePath(file.getPath());
                    taskInfo.setLocalFile(true);
                    taskInfo.setTaskType(taskType);
                }
                return taskInfo;
            }
        }).subscribe(new Consumer<TaskInfo>() {
            @Override
            public void accept(TaskInfo taskInfo) throws Exception {
                dataList.add(taskInfo);
            }
        }, new Consumer<Throwable>() {
            @Override
            public void accept(Throwable throwable) throws Exception {
                throwable.printStackTrace();
            }
        }, new Action() {
            @Override
            public void run() throws Exception {
                getV().onSuccess(true, dataList);
            }
        });
    }

    private void queryServerTask(TaskTypeEnum typeEnum){
        String dir;
        final int taskType = typeEnum.getType();

        List<TaskInfo> list =   EntityManager.getInstance().queryTaskInfo(taskType,false);
        if (Kits.Empty.check(list)) {
            getV().showToast("您还导入任务文件");
        }else{
            getV().onSuccess(true, list);
        }
    }


    private Observable<List<TaskItemInfo>> getParser(final XSSFSheet sheet, final int rwosCount, final int threadCount, final int startIndex, final TaskInfo taskInfo) {
        Observable<List<TaskItemInfo>> observable = Observable.create(new ObservableOnSubscribe<List<TaskItemInfo>>() {
            @Override
            public void subscribe(ObservableEmitter<List<TaskItemInfo>> e) throws Exception {
                NLog.d("getParser", "getParser=" + Thread.currentThread() + " startIndex=" + startIndex);

                List dataList = new ArrayList();
                for (int i = startIndex; i < rwosCount; i = i + threadCount) {
                    XSSFRow xssfRow = sheet.getRow(i);
                    NLog.d("getParser", "thread=" + Thread.currentThread() + " i=" + i);
                    TaskItemInfo itemInfo = getTaskItemInfo(sheet, xssfRow, taskInfo.getTaskType());
                    itemInfo.setTaskName(taskInfo.getTask_name());
                    itemInfo.setParentId(taskInfo.get_ID());
                    itemInfo.setFilePath(taskInfo.getTaskFilePath());
                    dataList.add(itemInfo);
                }
                EntityManager.getInstance().saveTaskItemInfo(dataList);
                e.onNext(dataList);
                e.onComplete();
            }
        }).subscribeOn(Schedulers.io());
        return observable;
    }


    public void saveTaskInfo(final TaskInfo taskInfo) throws Exception {
        getV().showLoadDialog();
        Observable.just(taskInfo).map(new Function<TaskInfo, XSSFSheet>() {
            @Override
            public XSSFSheet apply(TaskInfo taskInfo) throws Exception {
                EntityManager.getInstance().saveTaskInfo(taskInfo);
                EntityManager.getInstance().delTaskItemInfoByParentId(taskInfo.get_ID());
                InputStream inputStream = new FileInputStream(taskInfo.getTaskFilePath());
                XSSFWorkbook workbook = new XSSFWorkbook(inputStream);
                XSSFSheet sheet = workbook.getSheetAt(0);
                if (null != inputStream) {
                    inputStream.close();
                }
                return sheet;
            }
        }).map(new Function<XSSFSheet, List<TaskItemInfo>>() {
            @Override
            public List<TaskItemInfo> apply( XSSFSheet sheet) throws Exception {
                List<TaskItemInfo> dataList = new ArrayList();
                int rowsCount = sheet.getPhysicalNumberOfRows();
                for (int i = 1; i < rowsCount; i ++) {
                    XSSFRow xssfRow = sheet.getRow(i);
                    TaskItemInfo itemInfo = getTaskItemInfo(sheet, xssfRow, taskInfo.getTaskType());
                    itemInfo.setTaskName(taskInfo.getTask_name());
                    itemInfo.setParentId(taskInfo.get_ID());
                    itemInfo.setFilePath(taskInfo.getTaskFilePath());
                    dataList.add(itemInfo);
                }
                EntityManager.getInstance().saveTaskItemInfo(dataList);

                return dataList;
            }
        }).subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<List<TaskItemInfo>>() {
                    @Override
                    public void accept(List<TaskItemInfo> result) throws Exception {
                        NLog.d("LocalTask", "accept -result =" + result.size());
                        NLog.d("LocalTask", "complete");
                        taskInfo.setHadImported(true);
                        taskInfo.setCreateTime(Calendar.getInstance().getTimeInMillis());
                        EntityManager.getInstance().saveTaskInfo(taskInfo);
                        getV().importSuccess(taskInfo);
                    }
                }, new Consumer<Throwable>() {
                    @Override
                    public void accept(Throwable throwable) {
                        NLog.d("LocalTask", "error");
                        getV().showToast("文件错误,请重新导入2！");
                        saveCrash(throwable.getMessage());
                        throwable.printStackTrace();
                    }
                }, new Action() {
                    @Override
                    public void run() throws Exception {

                    }
                });


    }


    private TaskItemInfo getTaskItemInfo(XSSFSheet sheet, Row row, int taskType) {

        int rowNum = row.getRowNum();
        int firstCellNum = row.getFirstCellNum();
        int lastCellNum = row.getLastCellNum();

        NLog.d("getTaskItemInfo", "rowNum=" + rowNum + " firstCellNum=" + firstCellNum + " lastCellNum=" + lastCellNum);
        TaskItemInfo info = new TaskItemInfo();
        info.setRowIndex(rowNum);
        for (int i = firstCellNum; i < lastCellNum; i++) {
            try{
                Cell cell = row.getCell(i);
                info.setCellIndex(firstCellNum);


                XSSFCell xssfCell = sheet.getRow(0).getCell(i);
                if (null == xssfCell) {
                    continue;
                }
                String cellTitle = xssfCell.getStringCellValue();
                String value = convertCellValueToString(cell, cellTitle.contains("日期"));
                String cellType;
                if (null == cell) {
                    cellType = null;
                } else {
                    cellType = "" + cell.getCellType();
                }
                NLog.d("getTaskItemInfo", "i=" + i + " cellTitle=" + cellTitle + " value=" + value + " cellType=" + cellType);
                setItemValue(info, cellTitle, value);

            }catch (Exception e){
                e.printStackTrace();
            }

        }
        setIsLeak(info);
        switch (taskType) {
            case 0:
            case 2:
                String testPerson = info.getTestPerson();
                String testValue = info.getTestValue();
                if (!TextUtils.isEmpty(testPerson)
                        && !TextUtils.equals(testPerson, "null")
                        && !TextUtils.equals(testValue, "null")
                        && !TextUtils.isEmpty(testValue)) {
                    info.setIsHadTest(true);
                }
                break;
            case 1:
                String repeatPerson = info.getRepeatPerson();
                String repeatValue = info.getRepeatValue();
                if (!TextUtils.isEmpty(repeatPerson)
                        && !TextUtils.equals(repeatPerson, "null")
                        && !TextUtils.equals(repeatValue, "null")
                        && !TextUtils.isEmpty(repeatValue)) {
                    info.setIsHadTest(true);
                }
                break;
        }
        return info;
    }

    private TaskItemInfo setItemValue(TaskItemInfo info, String cellTitle, String value) {
        switch (cellTitle) {
            case "装置":
                info.setDevice(value);
                break;
            case "区域":
                info.setArea(value);
                break;
            case "设备":
                info.setEquipment(value);
                break;
            case "标签号":
                info.setLabel(value);
                break;
            case "位置描述":
                info.setLocationDesc(value);
                break;
            case "组件类型":
                info.setAssemblyType(value);
                break;
            case "组件子类型":
                info.setAssemblyChildType(value);
                break;
            case "泄漏阈值":
                info.setLeakValue(value);
                break;
            case "检测最小停留时间(秒)":
                info.setMinStopTime(value);
                break;
            case "检测日期":
                info.setTestDate(value);
                break;
            case "检测仪器":
                info.setTestDevice(value);
                break;
            case "检测值":
                info.setTestValue(value);
                break;
        /*    case "是否泄漏":
                info.setIsLeak(value);
                break;*/
            case "泄漏部位":
                info.setLeakLocation(value);
                break;
            case "背景值":
                info.setBackGround(value);
                break;
            case "室内":
                info.setIndoor(value);
                break;
            case "检测路径":
                info.setTestPath(value);
                break;
            case "每分滴漏数":
                info.setLeakSpeed(value);
                break;
            case "检测人员":
                info.setTestPerson(value);
                break;
            case "组件图片":
                info.setTestPic(value);
                break;
            case "备注":
                info.setDesc(value);
                break;
            case "复测日期":
                info.setRepeatDate(value);
                break;
            case "复测仪器":
                info.setRepeatDevice(value);
                break;
            case "复测值":
                info.setRepeatValue(value);
                break;
            case "复测人员":
                info.setRepeatPerson(value);
                break;
            case "维修日期":
                info.setRepairDate(value);
                break;
            case "维修措施":
                info.setRepairMethed(value);
                break;
            case "维修人员":
                info.setRepairPerson(value);
                break;
            default:
        }
        return info;
    }

    private void setIsLeak(TaskItemInfo itemInfo ){
        String testValueStr = itemInfo.getTestValue();
        String backGroundStr = itemInfo.getBackGround();
        String repeatValueStr = itemInfo.getRepeatValue();
        String leakValue = itemInfo.getLeakValue();

        if(!TextUtils.isEmpty(testValueStr) &&!TextUtils.isEmpty(backGroundStr)&& !TextUtils.isEmpty(leakValue) ){
            if (isLeak(leakValue,testValueStr,backGroundStr)) {
                itemInfo.setIsLeak("1");
            }else{
                itemInfo.setIsLeak("0");
            }
            double testValue = DoubleUtil.getDouble(testValueStr,1)-DoubleUtil.getDouble(backGroundStr,1);
            itemInfo.setTestValue( String.valueOf(DoubleUtil.getDouble(testValue,1)));
        }
        if(!TextUtils.isEmpty(repeatValueStr) &&!TextUtils.isEmpty(backGroundStr)&& !TextUtils.isEmpty(leakValue) ){
            if (isLeak(leakValue,repeatValueStr,backGroundStr)) {
                itemInfo.setIsLeak("1");
            }else{
                itemInfo.setIsLeak("0");
            }
            double testValue = DoubleUtil.getDouble(repeatValueStr,1)-DoubleUtil.getDouble(backGroundStr,1);
            itemInfo.setRepeatValue( String.valueOf(DoubleUtil.getDouble(testValue,1)));
        }
        NLog.d("setIsLeak","testValueStr="+testValueStr+" backGroundStr="+backGroundStr+" leakValue="+leakValue +" testValue="+itemInfo.getTestValue());
    }
    public boolean isLeak(String leakValueStr, String testValueStr, String backValueStr) {

        try {
            double leakValue = Double.parseDouble(leakValueStr);
            double testValue = Double.parseDouble(testValueStr);
            double backgroundValue = Double.parseDouble(backValueStr);
            return (testValue-backgroundValue) >= leakValue;
        } catch (Exception ex) {
            return false;
        }
    }

    private String convertCellValueToString(Cell cell, boolean isDate) {
        if (cell == null) {
            return "";
        }
        if (isDate) {
            try {
                Date date = cell.getDateCellValue();
                if (null != date) {
                    return Kits.Date.getYmdhms2(date.getTime());
                }else{
                    return "";
                }
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
        String returnValue = "";
        switch (cell.getCellType()) {
            case 0: // 数字
                Double doubleValue = cell.getNumericCellValue();
                String valueStr = String.valueOf(doubleValue);

                DecimalFormat df;
                if (valueStr.contains(".0")) {
                    df = new DecimalFormat("0");
                } else {
                    df = new DecimalFormat("0.0");
                }
                NLog.d("valueStr", "valueStr=" + valueStr);
                returnValue = df.format(doubleValue);
                break;
            case 1: // 字符串
                returnValue = cell.getStringCellValue();
                break;
            case 4: // 布尔
                Boolean booleanValue = cell.getBooleanCellValue();
                returnValue = booleanValue.toString();
                break;
            case 3: // 空值
                break;
            case 2: // 公式
                returnValue = cell.getCellFormula();
                break;
            case 5: // 故障
                cell.getDateCellValue();
                break;
            default:
                break;
        }
        NLog.d("valueStr", "cellType = " + cell.getCellType() + " Value=" + returnValue);
        return returnValue;
    }

    public void del(List<TaskInfo> delList) {
        for (TaskInfo info : delList) {
            if (null != info.get_ID()) {
                EntityManager.getInstance().delTaskInfo(info);
            }
            File file = new File(info.getTaskFilePath());
            if (null != file && file.exists()) {
                file.delete();
            }
        }
    }

    public void saveCrash(String content) {
        String sRoot = Environment.getExternalStorageDirectory().getAbsolutePath();//获取跟目录
        String targetDir = sRoot + "/检测系统/错误日志";
        long time = Calendar.getInstance().getTimeInMillis();
        String fileName = Kits.Date.getYmdhms(time) + ".txt";
        Kits.File.writeFile(targetDir + File.separator + fileName, content);
    }


    public void startUpload(List<TaskInfo> list) {
        getV().showLoadDialog();
        UploadHelper uploadHelper = new UploadHelper(new UploadHelper.UploadListener() {
            @Override
            public void uploadSuccess() {
                getV().disLoadDialog();
            }

            @Override
            public void uploadFail(int code, String message) {
                getV().notifyDataSetChanged();
                getV().disLoadDialog();
            }
        });
        uploadHelper.startUpload(list);
    }





}
